package com.yushu.authority.controller;

import com.yushu.authority.pojo.bo.PmUser;
import com.yushu.authority.pojo.vo.PmUserVO;
import com.yushu.common.anno.LogAop;
import com.yushu.common.shiro.ShiroUtil;
import com.yushu.common.util.random.Random;
import com.yushu.common.util.result.Result;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;

import static com.yushu.common.shiro.ShiroUtil.getSessionAttribute;


/**
 * 用户登录
 * @author test
 * @CreateDate 2020-12-03 15:47:25
 */
@RestController
@RequestMapping("/sysLogin")
public class LoginController {

    private Logger logger = Logger.getLogger(LoginController.class);
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private Producer producer;


    /**
     * 验证校验码信息
     * 2020-12-03 15:47:25
     */
    @ResponseBody
    @RequestMapping(value = "/captcha", method = RequestMethod.POST)
    public boolean captcha(@RequestBody String captcha) {
        boolean isUsed = false;
        String kaptcha = ShiroUtil.getCaptcha(Constants.KAPTCHA_SESSION_KEY, isUsed);

        if (StringUtils.isEmpty(captcha)) {
            isUsed = false;
            return false;
        } else if (!kaptcha.equalsIgnoreCase(captcha)) {//不区分大小写
            isUsed = false;
            return false;
        } else {
            isUsed = true;
            return true;
        }
    }

    /**
     * <pre>
     *
     * </pre>
     *
     * @param
     * @return void
     * @author test
     * @since 2020-12-03 15:47:25
	 * 2020-12-03 15:47:25
     **/
    @RequestMapping("captcha.jpg")
    public void captchaJpg(HttpServletResponse response, HttpServletRequest request) throws ServletException, IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //生成文字验证码
        String text = producer.createText();
        //   FIXME: 2020-12-03 15:47:25 这个地方验证码需要修改

        String ip = request.getRemoteAddr();
        if (StringUtils.equals("0:0:0:0:0:0:0:1", ip)) {
            text = Random.ToRandom(4);
        }


        //生成图片验证码
        BufferedImage image = producer.createImage(text);
        //保存到shiro session
        ShiroUtil.setSessionAttribute(Constants.KAPTCHA_SESSION_KEY, text);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
    }


    /**
     * 获取用户真实IP地址，不使用request.getRemoteAddr()的原因是有可能用户使用了代理软件方式避免真实IP地址,
     * 可是，如果通过了多级反向代理的话，X-Forwarded-For的值并不止一个，而是一串IP值
     *
     * @return ip
     */
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        System.out.println("x-forwarded-for ip: " + ip);
        if (ip != null && ip.length() != 0 && !"unknown".equalsIgnoreCase(ip)) {
            // 多次反向代理后会有多个ip值，第一个ip才是真实ip
            if (ip.indexOf(",") != -1) {
                ip = ip.split(",")[0];
            }
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
//            System.out.println("Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
//            System.out.println("WL-Proxy-Client-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_CLIENT_IP");
//            System.out.println("HTTP_CLIENT_IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("HTTP_X_FORWARDED_FOR");
//            System.out.println("HTTP_X_FORWARDED_FOR ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("X-Real-IP");
//            System.out.println("X-Real-IP ip: " + ip);
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
//            System.out.println("getRemoteAddr ip: " + ip);
        }
//        System.out.println("获取客户端ip: " + ip);
        return ip;
    }

    /**
     * 用户登录
     * 2020-12-03 15:47:25
     *
     * @param userVO
     * @return
     */
    @LogAop("登录")
    @ResponseBody
    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    public Result login(@RequestBody PmUserVO userVO, HttpSession session, HttpServletRequest request) {

        String ip = request.getRemoteAddr();
        if (StringUtils.equals("0:0:0:0:0:0:0:1", ip)) {
            ip = "120.78.205.78";
        }
        String address = "";


        //1、获取subject对象的实例
        Subject currentUser = SecurityUtils.getSubject();

        PmUser user = new PmUser();
        //2、判断当前用户是否已经登录
        if (currentUser.isAuthenticated() == false) {//未登录

            //用户名和密码封装到指定的类型当中
            //Shiro实现登录
            UsernamePasswordToken token = new UsernamePasswordToken(userVO.getUserName(), userVO.getPassword());

            try {
                currentUser.login(token);
//                user = (User) SecurityUtils.getSubject().getPrincipal();
//                session.setAttribute("user", user);
//                TODO 2019年10月25日11:56:44 IP 地址
                /*try {
                    address = HttpClientUtil.getAddresses("ip=" + ip, "utf-8");

                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }*/
//                address = ip;
                ShiroUtil.setSessionAttribute("ip", address);
                return Result.success("登录成功");
            } catch (UnknownAccountException e) {
                e.printStackTrace();
                return Result.error("用户不存在");

            } catch (IncorrectCredentialsException e) {
                e.printStackTrace();
                return Result.error("密码错误");

            } catch (AuthenticationException e) {
                e.printStackTrace();
                return Result.error("认证失败");

            } catch (Exception e) {
                e.printStackTrace();
                return Result.error("用户不存在");
            }


       /* } catch (ExcessiveAttemptsException ex) {
            log.info(username + "帐号被锁定1小时！", ex);
        } catch (UnknownAccountException uae) {
            log.info(username + "账户不存在!", uae);
        } catch (IncorrectCredentialsException ice) {
            log.info(username + "密码不正确!", ice);
        } catch (LockedAccountException lae) {
            log.info(username + "账户被禁了!", lae);
        } catch (AuthenticationException ae) {
            log.info(username + "用户名或密码错误！", ae);
        } catch (UnknownSessionException ue) {
            log.info("登录session失效" + sessionId, ue);

        }*/

        } else {
            //用户已经登录
            return Result.success("登录成功");

        }
    }


//    /**
//     * 用户退出，跳转到首页
//     * 2020-12-03 15:47:25
//     */
//    @LogAop("退出")
//    @RequestMapping(value = "/logout", method = RequestMethod.GET)
//    public String logout(HttpSession session) {
//
//        PmUser sessionUser = ShiroUtil.getSessionUser();
//        PmUserVO userCache = (PmUserVO) redisTemplate.opsForValue().get("userSession_" + sessionUser.getId());
//        if (null != userCache) {
//            redisTemplate.delete("userSession_" + sessionUser.getId());
//            redisTemplate.delete("SysMenuService_queryMenuTree_" + sessionUser.getId());
//        }
//
//        logger.info("用户退出");
//        // 登出操作
//        SecurityUtils.getSubject().logout();
//        return "redirect:/";
//        /*
//        try {
////            PmUserVO user = ShiroUtil.getSessionUser();
//            //FIXME 如果设置了redis的过期时间，就不需要手动删除redis缓存了
////            redisTemplate.delete("_queryMenuTree_" + user.getId());
//            subject.logout();
//        } catch (Exception e) {
//            logger.info(e.getMessage());
//            e.printStackTrace();
//        } finally {
//            return "redirect:/";
//        }*/
//
//    }
//
//
//    /**
//     * 跳转到注册页面
//     * 2020-12-03 15:47:25
//     */
//    @RequestMapping(value = "/toRegister", method = RequestMethod.GET)
//    public String toRegister(Model model, HttpServletRequest request) {
//
//        return "ins_register";
//    }
//    /**
//     * 跳转到邮箱忘记密码页面
//     * 2020-12-03 15:47:25
//     */
//    @RequestMapping(value = "/toForgetPass", method = RequestMethod.GET)
//    public String toForgetPass(Model model, HttpServletRequest request) {
//        return "ins_forget_password";
//    }
//
//    /*跳转到忘记密码页面*/
//     @RequestMapping(value = "/toForgetPassword",method = RequestMethod.GET)
//     public String toForgetPassword(Model model, HttpServletRequest request){
//         return "ins_validation_password";
//     }
//
//    /**
//     * 跳转到修改密码页面
//     * 2020-12-03 15:47:25
//     */
//    @RequestMapping(value = "/toEditPass", method = RequestMethod.GET)
//    public String toEditPass(Model model, HttpServletRequest request) {
//   		PmUser sessionUser = ShiroUtil.getSessionUser();
//        model.addAttribute("title", "修改密码");
//        model.addAttribute("data", sessionUser);
//        model.addAttribute("page", "ins_edit_password");
//        return "menuPage";
//    }
//
//    /**
//     * 跳转到登录页面
//     * 2020-12-03 15:47:25
//     */
//    @RequestMapping(value = "/toLogin", method = RequestMethod.GET)
//    public String toLogin(Model model, HttpServletRequest request) {
//        String ip = request.getRemoteAddr();
//        String captcha = "";
//        if (StringUtils.equals("0:0:0:0:0:0:0:1", ip)) {
//            captcha = "123456";
//        }
//        model.addAttribute("captcha", captcha);
//        return "ins_login";
//    }
//
//    /**
//     * 跳转到登录页面
//     * 2020-12-03 15:47:25
//     */
//    @RequestMapping(value = "/toSwagger", method = RequestMethod.GET)
//    public String toSwagger(Model model) {
//        model.addAttribute("title", "swagger管理");
//        model.addAttribute("page", "swagger-ui.html");
//        return "fullPageNoTail";
//    }
//
//
//    /**
//     * 方法模块拖拽设计
//     * 2020-12-03 15:47:25
//     *
//     * @param model
//     * @return
//     */
//    @RequestMapping(value = "/jsplumbPage", method = RequestMethod.GET)
//    public String jsplumbPage(Model model) {
//        model.addAttribute("title", "方法模块拖拽设计");
//        model.addAttribute("page", "/useFullPage/jsplumbgun/index");
//        return "fullPage";
//    }
//
//
//    @RequiresPermissions("user:create")
//    @RequestMapping(value = "testShiro")
//    @ResponseBody
//    public String testShiro() {
//        System.out.println("测试Shiro");
//        return "测试Shiro";
//    }
}
